#pragma once
#ifndef __IASSISTGEN2_UICRM_H
#define __IASSISTGEN2_UICRM_H

#include <map>
#include <string>
#include <vector>
#include "UIModuleDef.h"

#define BLOCK_GENERAL			"RTC-BLOCK-GENERAL"
#define MODULE_NOT_LOAD			"N/A"
#define MODULE_ADDRESS_PREFIX	"MODULE.ADDRESS."
#define SOCKET_SERVER_ADDRESS	"SOCKET.SERVER.ADDRESS"
#define DEFAULT_SOCKET_PORT		40050
#define MODULE_ADDRESS_LOCAL	"127.0.0.1"
#define DEFAULT_MAIN_CONFIG		"../Common/Resources/main-SmartHome.config"
#define DEFAULT_USER_CONFIG		"./usersetting.config"

class UIConfig
{
public:
	UIConfig();
	~UIConfig();
	
	std::string* getValue(std::string blockName, std::string parameterName);
	void setValue(std::string blockName, std::string parameterName, std::string value);
	void getAllParameters(std::string blockName, std::vector<std::string> &ret);

private:
	std::map<std::string, std::map<std::string, std::string> > m_mapBlockMap;		///< Data stucture to store properties
};

class UIConfigResourceManager
{
public:
	static UIConfigResourceManager* getInstance();
	static void create(const char* mainConfigName, const char* userConfigName);
	static void release();

	bool getStringValue	(UIModuleType moduleType, std::string blockName, std::string parameterName, std::string &ret);
	bool getIntValue	(UIModuleType moduleType, std::string blockName, std::string parameterName, int &ret);
	bool getFloatValue	(UIModuleType moduleType, std::string blockName, std::string parameterName, float &ret);
	bool getBoolValue	(UIModuleType moduleType, std::string blockName, std::string parameterName, bool &ret);
	bool getFileName	(UIModuleType moduleType, std::string blockName, std::string parameterName, std::string &ret);

	bool getStringList	(UIModuleType moduleType, std::string blockName, std::string parameterName, std::vector<std::string> &ret);
	bool getIntList		(UIModuleType moduleType, std::string blockName, std::string parameterName, std::vector<int> &ret);
	bool getFloatList	(UIModuleType moduleType, std::string blockName, std::string parameterName, std::vector<float> &ret);
	bool getBoolList	(UIModuleType moduleType, std::string blockName, std::string parameterName, std::vector<bool> &ret);
	bool getFileList	(UIModuleType moduleType, std::string blockName, std::string parameterName, std::vector<std::string> &ret);
	void getAllParameterNames(UIModuleType moduleType, std::string blockName, std::vector<std::string> &paraNames);

	bool isLocalModule(UIModuleType moduleType);
	bool isLocalSocketServer(void);
	std::string getSocketServerAddr(void)	{	return m_socketServerAddress;	}
	int getSocketServerPort(void)			{	return m_socketServerPort;		}

private:
	UIConfigResourceManager(const char* mainConfigName, const char* userConfigName);
	~UIConfigResourceManager(void);

	static UIConfigResourceManager* m_pInstance;

	void loadConfig(UIModuleType moduleType, std::string configFile);
	std::string* getValue(UIModuleType moduleType, std::string blockName, std::string parameterName);
	bool parseListValue(std::string* value, std::vector<std::string> &items);

	std::map<UIModuleType, UIConfig>	m_configs;
	std::vector<UIModuleType>			m_localModules;
	std::map<std::string, std::string>	m_userVariables;
	std::map<std::string, std::string>	m_variables;
	std::string							m_socketServerAddress;
	int									m_socketServerPort;
	std::vector<std::string>			m_localIPAddress;
	
	std::string getDir(std::string filePath) 
	{
		std::string curDir = filePath;
		size_t pos = curDir.find_last_of("\\/");
		if (pos == std::string::npos) {
			return ".";
		}
		return curDir.substr(0, pos);
	}

	std::string replaceVar(std::string str) 
	{
		if (str.find("$") == std::string::npos)
			return str;

		std::string replaceStr = str;
		size_t begin_var = replaceStr.find("$");
		while (begin_var != std::string::npos) {
			size_t end_var = replaceStr.find_first_not_of("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz-$", begin_var);
			std::string var = replaceStr.substr(begin_var, end_var-begin_var);
			if (m_variables.find(uppercase(var)) != m_variables.end()) {
				replaceStr = replaceStr.replace(begin_var, end_var-begin_var, m_variables[uppercase(var)]);
			}
			else {
				// error
			}
			begin_var = replaceStr.find("$");
		}
		return replaceStr;
	}

	bool isLocalAddress(std::string address)
	{
		if (equalsIgnoreCase(address, "local") || equalsIgnoreCase(address, MODULE_ADDRESS_LOCAL))
			return true;
		for (unsigned int iAddr = 0; iAddr < m_localIPAddress.size(); iAddr++) {
			if (equalsIgnoreCase(m_localIPAddress[iAddr], address))
				return true;
		}
		return false;
	}
};

#endif
